package com.github.wxiaoqi.security.biz.codex.biz;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.wxiaoqi.security.auth.client.jwt.ServiceAuthUtil;
import com.github.wxiaoqi.security.auth.common.config.ServiceAuthConfig;
import com.github.wxiaoqi.security.auth.common.config.UserAuthConfig;
import com.github.wxiaoqi.security.biz.codex.entity.MarCoupon;
import com.github.wxiaoqi.security.biz.codex.entity.MarCouponRev;
import com.github.wxiaoqi.security.biz.codex.entity.MarIntegral;
import com.github.wxiaoqi.security.biz.codex.entity.MarIntegralRev;
import com.github.wxiaoqi.security.biz.codex.entity.MarRandomCoupon;
import com.github.wxiaoqi.security.biz.codex.mapper.MarCouponMapper;
import com.github.wxiaoqi.security.biz.codex.mapper.MarCouponRevMapper;
import com.github.wxiaoqi.security.biz.codex.mapper.MarIntegralMapper;
import com.github.wxiaoqi.security.biz.codex.mapper.MarIntegralRevMapper;
import com.github.wxiaoqi.security.biz.codex.mapper.MarRandomCouponMapper;
import com.github.wxiaoqi.security.biz.feign.CrmFeign;
import com.github.wxiaoqi.security.common.admin.pay.response.BaseResponse;
import com.github.wxiaoqi.security.common.biz.request.CoupIntegRevCrmReq;
import com.github.wxiaoqi.security.common.biz.request.MarketingReceiveReq;
import com.github.wxiaoqi.security.common.biz.response.BaseCoupInfo;
import com.github.wxiaoqi.security.common.biz.response.BaseIntegralInfo;
import com.github.wxiaoqi.security.common.msg.Constant;
import com.github.wxiaoqi.security.common.util.DateUtils;

/**
 * 红包、积分领取校验
 * 
 * @author muyongq
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CommonBiz {

	private final static Logger logger = LoggerFactory.getLogger(CommonBiz.class);

	@Autowired
	private MarCouponMapper couponMapper;
	@Autowired
	private MarIntegralMapper integralMapper;
	@Autowired
	private MarIntegralMapper marIntegralMapper;
	@Autowired
	private MarIntegralRevMapper integralRevMapper;
	@Autowired
	private MarCouponRevMapper couponRevMapper;
	@Autowired
	private MarRandomCouponMapper randomCouponMapper;
	@Autowired
	private CrmFeign crmFeign;
	@Autowired
	private PersonalCouponRelationBiz personalCouponRelationBiz;
	
    @Autowired
    private ServiceAuthConfig serviceAuthConfig;

    @Autowired
    private UserAuthConfig userAuthConfig;

    @Autowired
    private ServiceAuthUtil serviceAuthUtil;
	
	/**
	 * 查询红包或者积分是否可以领取
	 * 
	 * @param businessType
	 *            业务类型，incidentId 事件ID
	 */
	public Object getCoupInciRev(String businessType, String incidentId) {
		try {
			/**
			 * 根据事件查询配置的可以领取的红包信息
			 */
			if (null != businessType && Constant.COUPON_CODE.equals(businessType)) {
				List<MarCoupon> marcoupons = couponMapper.getCouponsByincCode(incidentId);
				if (null != marcoupons && marcoupons.size() > 0) {
					return marcoupons;
				}
			}
			/**
			 * 根据事件查询配置的可以领取的积分信息
			 */
			if (null != businessType && Constant.INTEGRAL_CODE.equals(businessType)) {
				List<MarIntegral> marIncidents = marIntegralMapper.selectIntegralsByIncCode(incidentId);
				if (null != marIncidents && marIncidents.size() > 0) {
					return marIncidents;
				}
			}
		} catch (Exception e) {
			logger.info("获取可领取的红包或者积分报错" + e.getMessage());
			e.printStackTrace();
			return null;
		}
		return null;
	}

	/**
	 * 校验红包、积分 是否达到领取的设置上限
	 * 
	 * @param obj
	 *            实体 ;businessType 业务类型： 红包或者是积分
	 * @return true 表示超出领取上限 不能领取 ；false则表示没有超出 可以领取
	 */
	public boolean checkCoupInciLimit(Object obj, String businessType) {
		boolean checkCoupInLimit = false;// 是否超过领取上限
		int couIncAmt = 0;// 红包或者积分配置的领取上限
		int revcount = 0;// 红包或者积分领取数量统计
		try {
			if (null != businessType && Constant.COUPON_CODE.equals(businessType)) {
				MarCoupon marcoupon = (MarCoupon) obj;
				/**
				 * 统计出有效的红包领取记录
				 */
				couIncAmt = marcoupon.getCouAmt();// 红包设置的上限的数量
				String couid = marcoupon.getCouId();
				revcount = couponRevMapper.queryCountCoupRev(couid);// 统计该红包已经被领取的数量
			}
			if (null != businessType && Constant.INTEGRAL_CODE.equals(businessType)) {
				MarIntegral marIntegral = (MarIntegral) obj;
				/**
				 * 统计有效的积分领取数量
				 */
				couIncAmt = marIntegral.getIncNum();// 积分设置的领取上限的数量
				revcount = integralRevMapper.queryCountIntegRev(marIntegral.getIncCode());// 统计该红包已经被领取的数量
			}
			if (revcount >= couIncAmt) {
				checkCoupInLimit = true;// 超出了领取上限不能领取
			}
		} catch (Exception e) {
			logger.info("检验红包或者积分设置&领取数量上限报错" + e.getMessage());
			e.printStackTrace();
			return true;
		}
		return checkCoupInLimit;
	}

	/**
	 * 校验用户领取红包、积分 的领取上限 对象：红包/积分 规则： 每天几次、每周几次、每月几次 都是以天为单位，有且只有一种规则。
	 * 根据待领取的红包配置的每天、每周、每天配置的领取规则 校验红包是否可领取
	 * 
	 * @param obj
	 *            实体 ;businessType 业务类型;merCusrNo 商户会员号
	 * @return true 表示超出领取上限 不能领取 ；false则表示没有超出 可以领取
	 */
	public boolean checkCoupIncRev(Object obj, String businessType, String merCusrNo) {
		boolean checkCoupInLimit = false;// 是否超过领取上限
		try {
			// 红包领取校验 :随机红包暂时不进行校验
			if (null != businessType && Constant.COUPON_CODE.equals(businessType)) {
				MarCoupon marcoupon = (MarCoupon) obj;
				if (Constant.COMMON_COUPON.equals(marcoupon.getCouType())) {// 如果是普通红包的去校验
																					// 随机红包不会检验。
					if (null != marcoupon.getEveryDay()) {// 每天统计
						int revbyday = couponRevMapper.countCounpRevByday(
								DateUtils.format(new Date(), DateUtils.DATE_PATTERN), merCusrNo, marcoupon.getCouId());
						if (revbyday >= marcoupon.getEveryDay()) {// 超出上限不能领取
							checkCoupInLimit = true;
						}
					}
					if (null != marcoupon.getEveryWeek()) {// 每周统计
						int revbyweek = couponRevMapper.countCounpRevBydate(DateUtils.datetimeAgo(-6),
								DateUtils.format(new Date(), DateUtils.DATE_PATTERN), merCusrNo, marcoupon.getCouId());
						if (revbyweek >= marcoupon.getEveryWeek()) {// 超出上限不能领取
							checkCoupInLimit = true;
						}
					}
					if (null != marcoupon.getEveryMonth()) {// 每月统计
						int revbyweek = couponRevMapper.countCounpRevBydate(DateUtils.datetimeAgo(-29),
								DateUtils.format(new Date(), DateUtils.DATE_PATTERN), merCusrNo, marcoupon.getCouId());
						if (revbyweek >= marcoupon.getEveryMonth()) {// 超出上限不能领取
							checkCoupInLimit = true;
						}
					}
				}
			}
			// 积分领取校验
			if (null != businessType && Constant.INTEGRAL_CODE.equals(businessType)) {
				MarIntegral marIntegral = (MarIntegral) obj;
				if (null != marIntegral.getEveryDay()) {// 每天统计
					int revbyday = integralRevMapper.countIntegRevByday(
							DateUtils.format(new Date(), DateUtils.DATE_PATTERN), merCusrNo,
							marIntegral.getIntegralId());
					if (revbyday >= marIntegral.getEveryDay()) {// 超出上限不能领取
						checkCoupInLimit = true;
					}
				}
				if (null != marIntegral.getEveryWeek()) {// 每周统计
					int revbyweek = integralRevMapper.countIntegRevBydate(DateUtils.datetimeAgo(-6),
							DateUtils.format(new Date(), DateUtils.DATE_PATTERN), merCusrNo,
							marIntegral.getIntegralId());
					if (revbyweek >= marIntegral.getEveryWeek()) {// 超出上限不能领取
						checkCoupInLimit = true;
					}
				}
				if (null != marIntegral.getEveryMonth()) {// 每月统计
					int revbyweek = integralRevMapper.countIntegRevBydate(DateUtils.datetimeAgo(-29),
							DateUtils.format(new Date(), DateUtils.DATE_PATTERN), merCusrNo,
							marIntegral.getIntegralId());
					if (revbyweek >= marIntegral.getEveryMonth()) {// 超出上限不能领取
						checkCoupInLimit = true;
					}
				}
			}
		} catch (Exception e) {
			checkCoupInLimit = true;
			logger.info("检验校验用户领取红包、积分 的领取上限报错" + e.getMessage());
			e.printStackTrace();
			return checkCoupInLimit;
		}
		return checkCoupInLimit;
	}

	/**
	 * 随机立减 对设置总金额的校验 指定事件触发的随机立减总金额不能大于设置的总金额
	 * 
	 * @param obj
	 *            实体 ;businessType 业务类型
	 * @return true 表示超出领取上限 不能领取 ；false则表示没有超出 可以领取
	 */
	public boolean checkSetAmount(Object obj, String businessType) {
		boolean checkLimit = false;// 是否超过领取上限
		if (null != businessType && Constant.RANDOM_CODE.equals(businessType)) {
			try {
				MarCoupon marcoupon = (MarCoupon) obj;
				if (Constant.RANDOM_COUPON.equals(marcoupon.getCouType())) {// 如果是随机立减
					String couponSum = couponRevMapper.getCouponAmtSum(marcoupon.getCouId());
					if (null != couponSum && !"".equals(couponSum)) {
						if (new BigDecimal(couponSum).compareTo(marcoupon.getCouSum()) > 0) {
							checkLimit = true;
						}
					}
				}
			} catch (Exception e) {
				checkLimit = true;
				logger.info("随机立减 或者随机红包 对设置总金额的校验报错：" + e.getMessage());
				e.printStackTrace();
				return checkLimit;
			}

		}
		return checkLimit;

	}

	/**
	 * 校验用户是否领取过红包、积分 对象 红包/积分 根据支付订单号、事件编号查询用户是否领取过红包积分
	 * 
	 * @param obj
	 * @param businessType
	 * @param merOrderNo
	 * @param incCode
	 * @return
	 */
	public boolean chechIsReceived(Object obj, String businessType, String merOrderNo) {
		boolean checkLimit = false;
		try {
			if (StringUtils.isEmpty(merOrderNo)) {
				checkLimit = false;
			} else {
				// 红包领取校验
				if (null != businessType && Constant.COUPON_CODE.equals(businessType)) {
					MarCoupon marcoupon = (MarCoupon) obj;
					String incCode = marcoupon.getIncCode();
					Integer res = couponRevMapper.getCouponRevByOrderNoAndIncCode(merOrderNo, incCode);
					if (res > 0) {
						logger.info("已经领取过红包。。。{}");
						checkLimit = true;
					}
				}
				// 积分领取校验
				if (null != businessType && Constant.INTEGRAL_CODE.equals(businessType)) {
					MarIntegral marIntegral = (MarIntegral) obj;
					String incCode = marIntegral.getIncCode();
					Integer res = integralRevMapper.getIntegralRevByOrderNoAndIncCode(merOrderNo, incCode);
					if (res > 0) {
						logger.info("已经领取过积分。。。{}");
						checkLimit = true;
					}
				}
			}
		} catch (Exception e) {
			checkLimit = true;
			logger.info("校验是否领取过红包/积分 报错：" + e.getMessage());
			e.printStackTrace();
			return checkLimit;
		}
		return checkLimit;
	}

	/**
	 * 红包或者积分领取
	 * 
	 * @param
	 * 
	 **/
	public boolean coupIncRevbyCrm(CoupIntegRevCrmReq coupIntegRevCrmReq, List<BaseCoupInfo> basecouponList,
			List<BaseIntegralInfo> baseintegralList, String merCustNo, String incidentId, String merOrderNo, String revType) {
		boolean isRevOk = false;
		//String requestStr=EntityUtils.BeanToJsonStr(coupIntegRevCrmReq);
		logger.info("手动领取红包/积分。。。{}"+coupIntegRevCrmReq);
		MarketingReceiveReq marketingReceiveReq = new MarketingReceiveReq();
		BaseResponse baseResponse = personalCouponRelationBiz.marketingReceive(marketingReceiveReq);
		try {
			if (baseResponse.getCode().equals("200")) {
				// 存入数据库红包或者积分领取记录
				saveCoupIntegRevRecord(basecouponList, baseintegralList, merCustNo, incidentId, merOrderNo,revType);
				isRevOk = true;
				logger.info("调用CRM服务领取成功-红包或者积分保存成功");
			} else {
				// 记录下错误信息
				logger.info("调用CRM服务领取报错：错误码---" + baseResponse.getCode() + "---错误信息--" + baseResponse.getMsg());
			}
		} catch (Exception e) {
			logger.info("事件触发的 红包/积分基础领取报错-存入数据库红包或者积分领取记录报错" + e.getMessage());
			e.printStackTrace();
		}
		return isRevOk;
	}

	/**
	 * 用户信息校验 调用CRM提供的接口
	 * 
	 * @param
	 * 
	 **/
	public String custBaseQuery(Map<String, Object> custReqMap) {
		String isRevOk = "false";
		Map<String, Object> result= crmFeign.queryPersonalInfo(custReqMap);
		try {
			String code = (String) result.get("code");
			String msg = (String) result.get("msg");
			if ("200".equals(code)) {
				isRevOk = "true";
				logger.info("调用CRM服务校验用户信息成功");
			} else {
				// 记录下错误信息
				logger.info("调用CRM服务校验用户信息报错：错误码---" + code + "---错误信息--" + msg);
			}
		} catch (Exception e) {
			logger.info("调用CRM服务校验用户信息报错：" + e.getMessage());
			e.printStackTrace();
		}
		return isRevOk;
	}

	/**
	 * 商户信息校验 调用CRM提供的接口
	 * 
	 * @param
	 * 
	 **/
	public String queryMerchantInfo(Map<String, Object> merReqMap) {
		String isRevOk = "false";
		Map<String, Object> result = crmFeign.queryMerchantInfo(merReqMap);
		try {
			String code = (String) result.get("code");
			String msg = (String) result.get("msg");
			if ("200".equals(code)) {
				isRevOk = "true";
				logger.info("调用CRM服务校验商户信息成功");
			} else {
				// 记录下错误信息
				logger.info("调用CRM服务校验商户信息报错：错误码---" + code + "---错误信息--" + msg);
			}
		} catch (Exception e) {
			logger.info("调用CRM服务校验商户信息报错：" + e.getMessage());
			e.printStackTrace();
		}
		return isRevOk;
	}

	/**
	 * 红包 领取：调用crm领取成功后，保存红包的领取记录
	 * 
	 * @param basecouponList 红包列表; baseintegralList 积分列表 ;merCustNo 商户会员号; incidentId 事件编号
	 */
	public void saveCoupIntegRevRecord(List<BaseCoupInfo> basecouponList, List<BaseIntegralInfo> baseintegralList,
			String merCustNo, String incidentId, String merOrderNo, String revType) {
		if (null != basecouponList && basecouponList.size() > 0) {// 红包
			for (BaseCoupInfo basecoup : basecouponList) {
				MarCouponRev couponRev = new MarCouponRev();
				couponRev.setCouId(basecoup.getCouponId());
				couponRev.setActId(basecoup.getActId());
				couponRev.setCouSerial(basecoup.getCouponSerialNo());
				couponRev.setIncCode(incidentId);
				couponRev.setMerCustNo(merCustNo);
				couponRev.setReceiverTime(new Date());
				couponRev.setSceneId(basecoup.getSceneId());
				couponRev.setMerorderno(merOrderNo);
				couponRev.setCouponAmt(basecoup.getCouponAmt());// 存入红包抵扣金额
				couponRev.setCouponLevel(basecoup.getCouLevel());
				couponRev.setRevType(revType);
				couponRevMapper.insertSelective(couponRev);
				if("1".equals(basecoup.getCouponType())){
					MarRandomCoupon randomCoupon = new MarRandomCoupon();
					randomCoupon.setCouId(basecoup.getCouponId());
					randomCoupon.setCouSerial(basecoup.getCouponSerialNo());
					randomCoupon.setIsReceived("01");
					randomCouponMapper.updateByID(randomCoupon);
				}
			}
		}
		if (null != baseintegralList && baseintegralList.size() > 0) {
			if (null != baseintegralList && baseintegralList.size() > 0) {
				for (BaseIntegralInfo baseIntegral : baseintegralList) {
					MarIntegral in = new MarIntegral();
					in.setIntegralId(baseIntegral.getIntegralId());
					MarIntegral integral = integralMapper.selectByIntegralId(baseIntegral.getIntegralId());
					// MarIntegral integral =
					// integralMapper.selectByPrimaryKey(baseIntegral.getIntegralId());
					if (null != integral) {
						MarIntegralRev integralRev = new MarIntegralRev();
						integralRev.setMerCustNo(merCustNo);
						integralRev.setIntegralAmt(Integer.parseInt(baseIntegral.getIntegralAmt()));
						integralRev.setReceiverTime(new Date());
						integralRev.setSceneId(integral.getSceneId());
						integralRev.setActId(integral.getActId());
						integralRev.setIncCode(incidentId);
						integralRev.setMerorderno(merOrderNo);
						integralRev.setIntegralId(integral.getIntegralId());
						integralRevMapper.insertSelective(integralRev);
					}
				}
			}
		}

	}

}
